﻿package code {
	import flash.display.MovieClip;
	
	public class Player extends MovieClip{
		
		// Varibles
		private const HAND_LIMIT:int = 7;
		private const INITIAL_HAND_COUNT:int = 3;
		
		// Cards
		private var cardDeck:Array;			// List of all cards to choose from
		private var totalDeck:Array;		// List of all cards that correspond per player theme
		private var handCards:Array;		// List of cards in the players hand
		private var storedCards:Array;		// List of cards in the players stored cards
		private var basicCards:Array;		// List of cards in the players basic cards		
		private var cardUsing:Card;			// current card being used
		private var modifiers:Array;
		
		// Name
		private var playerName:String;		// Name of the player
		
		// Stats
		private var attack:int;				// player attack stat
		private var defense:int;			// player defence stat
		private var hp:int;					// player hp stat
		private var speed:int;				// player speed stat
		private var mana:int;				// player mana stat
		private var poweredUp:Boolean;		// bool that tells if the player is currently powered up
		private var accuracy:Number;
		private var tempAttack:int;
		private var tempDefense:int;
		
		// inGame
		private var moveComplete:Boolean;	// bool to check if they made a move or not
		private var isAttacking:Boolean;		// bool to check if they are attacking
		private var attackAgain:Boolean;
		
		//XML
		private var xmlFile:XML;			// Players XML data
		
		// GUI
		private var gui:GUI;			// gui stuff
		
		// bool
		private var drawAttack:Boolean;
		
		// Properties		
		
		//PlayerName
		public function get PlayerName():String { return playerName; }
		public function set PlayerName(val:String){ playerName = val; }
		
		//Attack
		public function get Attack():int { return attack; }
		public function set Attack(val:int){ attack = val; }
		public function get TempAttack():int { return tempAttack; }
		public function set TempAttack(val:int){ tempAttack = val; }
		
		//Defense
		public function get Defense():int { return defense; }
		public function set Defense(val:int){ defense = val; }
		public function get TempDefense():int { return tempDefense; }
		public function set TempDefense(val:int){ tempDefense = val; }
		
		//Hp
		public function get Hp():int { return hp; }
		public function set Hp(val:int){ hp = val; }
		
		//Speed
		public function get Speed():int { return speed; }
		public function set Speed(val:int){ speed = val; }
		
		//Mana
		public function get Mana():int { return mana; }
		public function set Mana(val:int){ mana = val; }
		
		// Powered up
		public function get PoweredUp():Boolean{ return poweredUp; }
		public function set PoweredUp(val:Boolean){ poweredUp = val; }
		
		//Accuracy
		public function get Accuracy():Number { return accuracy; }
		public function set Accuracy(val:Number){ accuracy = val; }
		
		//MoveComplete
		public function get MoveComplete():Boolean { return moveComplete; }
		public function set MoveComplete(val:Boolean){ moveComplete = val; }
		
		//IsAttacking
		public function get IsAttacking():Boolean { return isAttacking; }
		public function set IsAttacking(val:Boolean){ isAttacking = val; }
		
		//Hand Cards
		public function get HandCards():Array { return handCards; }
		
		//Stored Cards
		public function get StoredCards():Array { return storedCards; }
		public function set StoredCards(val:Array){ storedCards = val; }
		
		//Basic Cards
		public function get BasicCards():Array { return basicCards; }
		
		//Card Using
		public function get CardUsing():Card { return cardUsing; }
		public function set CardUsing(val:Card){ cardUsing = val; }
		
		//Total Deck
		public function get TotalDeck():Array{ return totalDeck; }
		
		//Modifiers
		public function get Modifiers():Array{ return modifiers; }
		
		public function get Gui():GUI{ return gui; }
		
		public function get DrawAttack():Boolean { return drawAttack; }
		public function set DrawAttack(val:Boolean){ drawAttack = val; }
		
		public function get AttackAgain():Boolean { return attackAgain; }
		public function set AttackAgain(val:Boolean){ attackAgain = val; }
		
		// constructor code
		public function Player(xml:XML, num:int) {
			totalDeck = new Array();
			cardDeck = new Array();
			handCards = new Array();
			storedCards = new Array();
			basicCards = new Array();
			modifiers = new Array();
			
			gui = new GUI(num, this);
			accuracy = 1;
			xmlFile = xml;
			
			width *= 3;
			height *= 3;
			
			drawAttack = false;
			
			init();			
		}
		
		// Methods
		
		// Initializes the player
		public function init():void {			
			readIn();		
			initHand();
		}
		
		// reads in the xml
		public function readIn():void{
			playerName = xmlFile.@name;	
			attack = xmlFile.attack;
			defense = xmlFile.defense;
			hp = xmlFile.hp;
			speed = xmlFile.speed;
			mana = 10;
			
			for each(var card:XML in xmlFile.deck.card){
				totalDeck.push(new Card(card.@type,card.@name, card.@cost, card.@accuracy, card.@effect, card.@modifier, card.@description));
			}
			
			
			for each(var baseCard:XML in xmlFile.basicDeck.card){
				basicCards.push(new Card(baseCard.@type,baseCard.@name, baseCard.@cost, baseCard.@accuracy, baseCard.@effect, baseCard.@modifier, baseCard.@description));
			}
			poweredUp = false;
			
			shuffle();
		}
		
		// Shuffles the players deck
		private function shuffle():void {
			var indexes:Array = new Array();
			while(cardDeck.length != totalDeck.length){
				var indexToAdd:int = Math.random() * totalDeck.length;
				var canAdd = doesContain(indexToAdd, indexes);
				if(canAdd == false){  // checks to see if card has already been added
					indexes.push(indexToAdd);
					cardDeck.push(totalDeck[indexToAdd]);
				}
			}
		}
		
		// checks if an int is in the array
		private function doesContain(num:int, indexes:Array):Boolean{
			var container:Boolean = false;
			
			for each(var index:int in indexes){
				if(index == num){
					container = true;
					break;
				}
				else{
					container = false;
				}
			}
			return container;
		}
		
		// Draw Card from deck and add it to the hand
		public function drawCard():void {
			if(handCards.length < HAND_LIMIT && cardDeck.length > 0)
				handCards.push(cardDeck.pop());
		}
		
		// Choose Card
		public function chooseCard(index:int, handType:String):void {
			if(handType == "hand")
			{
				cardUsing = handCards[index];

				handCards.splice(index, 1);
			}
			else if(handType == "basic")
				cardUsing = basicCards[index];
			
			else if(handType == "stored")
				cardUsing = storedCards[index];
				
			mana -= cardUsing.ManaCost;
			moveComplete = true;
		}
		
		// Initialized Hand
		public function initHand():void {
			for(var i:int = 0; i < INITIAL_HAND_COUNT; i++)
			{
				drawCard();
			}
		}
		
		// sets player up for phase they are on
		public function switchPhase() {
			if(!IsAttacking){ // swithces to attacking
				IsAttacking = true;
				drawCard();
				drawAttack = true;
			}
			else{
				IsAttacking = false;
				drawAttack = false;
			}
		}

	}
	
}
